# Copyright 2015 ZhangZhaoyuan
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

require 'aliyunsdk/core/utils/api_util'
require 'aliyunsdk/core/client'
require 'aliyunsdk/core/auth/auth'
require 'securerandom'
module Aliyunsdk
  module Core

    # Public request
    module AcsRequest
      attr_accessor :format, :signature_method, :signature_params, :http_protocol
      attr_reader :http_method, :signature_version, :version, :signature

      # Constructor
      # @param format [String] JSON or XML
      # @param signature_method [String] HMAC-SHA1
      # @return [AcsRequest] request object
      def initialize(format, signature_method, signature_version, api_version)
        @format = format
        @version = api_version
        @signature_method = signature_method
        @signature_version = signature_version
        @http_method = ApiUtil::HTTP_GET_METHOD
        @http_protocol = ApiUtil::PROTOCOL_HTTPS
        @signature_params ||= {}
      end

      # Generate sign string
      # @return [String] sign string
      def generate_sign_string
        @signature_params.merge!({Format: @format, Version: @version,
                                  AccessKeyId: Client::AcsClient.access_key_id,
                                  SignatureMethod: @signature_method, Timestamp: ApiUtil.gen_timestamp,
                                  SignatureVersion: @signature_version, SignatureNonce: SecureRandom.uuid.gsub('-', '')})
        # order keys
        ordered_keys = @signature_params.keys.sort
        # encode & join keys and values
        sign_params = []
        ordered_keys.each { |key|
          sign_params << "#{ApiUtil.percent_encode key}=#{ApiUtil.percent_encode @signature_params[key]}" }
        query_string = sign_params.join '&'
        # generate sign string
        "#{@http_method}&#{ApiUtil.percent_encode '/'}&#{ApiUtil.percent_encode query_string}"
      end

      # Generate url parameters
      # @return [String] k=v&k1=v1...
      def generate_url_params
        url_params = []
        @signature = Auth.sign generate_sign_string, @signature_method
        req_params = @signature_params.merge({Signature: @signature})
        req_params.each_pair do |k, v|
          url_params << "#{k}=#{ApiUtil.percent_encode v}"
        end
        url_params.join '&'
      end
    end
  end
end
